<template>
    <div>
        <textarea ref="mycode" placeholder=""
                  class="codesql" />
    </div>
</template>
<style>
#cm-complete-0,#cm-complete-1,#cm-complete-2{
    z-index: 4000 !important;
}
.CodeMirror-code {
    font-size: 12px
}
</style>
<script setup>
import 'codemirror/theme/ambiance.css'
import 'codemirror/lib/codemirror.css'
import 'codemirror/addon/hint/show-hint.css'
import { defineProps, defineExpose, onMounted, toRefs, ref, watch } from 'vue'

const CodeMirror = require('codemirror/lib/codemirror') 
require('codemirror/addon/edit/matchbrackets')
require('codemirror/addon/selection/active-line')
require('codemirror/mode/sql/sql')
require('codemirror/addon/hint/show-hint')
require('codemirror/addon/hint/sql-hint')

const props = defineProps({
    mode: String,
    content: String,
    dbType: String,
    keywords: Object,
    height:  {
        type: Number,
        default: 400
    },
})

const { mode,content,dbType,keywords, height } = toRefs(props)
const width = ref('auto')

const mycode = ref()

var cm = {}

defineExpose({ 
    append:(sql) => {
        var val = cm.doc.getValue()
        cm.doc.setValue(`${val};\n${sql}\n`)
        var line = val.split('\n').length
        cm.setSelection({line: line, ch:0 },{line: line + sql.split('\n').length, ch:0 })
        cm.scrollIntoView({line: line, ch:0 })
    },
    setValue: (val)=>{
        cm.clearHistory()
        cm.doc.setValue(val)
        cm.refresh()
    },
    clearHistory: () => {
        cm.clearHistory()
        cm.focus()
        cm.setCursor(cm.lineCount(), 0)
        cm.refresh()
    },
    getSelectionOrValue: () => {
        return cm.doc.getSelection() || cm.doc.getValue()
    }
 })

onMounted(()=>{
    //选择对应代码编辑器的语言
    //text/x-sql, text/x-mysql, text/x-mariadb, text/x-cassandra, text/x-plsql, text/x-mssql, text/x-hive, text/x-pgsql, text/x-gql, text/x-gpsql. text/x-esper.
    // let theme = 'ambiance'//设置主题，不设置的会使用默认主题
    cm = CodeMirror.fromTextArea(mycode.value, {
        mode: mode.value, // 选择对应代码编辑器的语言
        indentWithTabs: true,
        smartIndent: true,
        lineNumbers: true,
        matchBrackets : true,
        autofocus: true,
        styleActiveLine: true,
        extraKeys: {"ctrl": "autocomplete"},
        hintOptions: {
            dbType: dbType.value,
            completeSingle: false,
            tables: {
                IOT_PUB_MGT: ["SYS_DEVICE", "SYS_USER", "SYS_ROLE", "AREA"],
                VIEW_DEVICE:[]
            }
        },
    })
    cm.setValue(content.value)
    cm.setSize(width.value, height.value)
    cm.on('focus', function(cm){
        var options = cm.getOption('hintOptions')
        if(JSON.stringify(options.tables) !== JSON.stringify(keywords.value)){
            var hintOptions  = cm.getOption('hintOptions')
            cm.setOption('hintOptions', { 
                ...hintOptions,
                tables: keywords.value,
            })
            cm.refresh()
        }
    })
    //处理弹窗提示
    cm.on("change", function (editor, change) {
        //处理Oralce表名小写时需要引号
        if(editor.options.hintOptions.dbType == 'Oracle' && change.origin == 'complete' 
            && change.text.length == 1 && change.text[0].toUpperCase() !== change.text[0]){
            var pos = editor.getCursor()
            var tok = editor.getTokenAt(pos)
            editor.replaceRange(`"${change.text[0]}"`, {line: pos.line, ch:tok.start},{line:pos.line, ch:tok.end})
        }
        //处理Mysql表名需要··
        if(editor.options.hintOptions.dbType == 'Oracle' && change.origin == 'complete' 
            && change.text.length == 1 && change.text[0].toUpperCase() !== change.text[0]){
            var pos1 = editor.getCursor()
            var tok1 = editor.getTokenAt(pos1)
            editor.replaceRange(`\`${change.text[0]}\``, {line: pos1.line, ch:tok1.start},{line:pos1.line, ch:tok1.end})
        }

        const ignore = ['', '#', '!', '-', '=', '@', '$', '%', '&', '+', ';', '(', ')', '*'];
        const ignoreToken = (text) => {
        if (text && text[0]) {
            for (const pre in ignore) {
            if (ignore[pre] === text[0]) {
                return true;
            }
            }
        } else {
            return true;
        }
        return false;
        }
        if (change.origin == "+input") {
        var text = change.text;
        //不提示
        if (!ignoreToken(text))
            setTimeout(function () { 
            editor.execCommand("autocomplete");
            }, 20);
        }
    })
})

watch(() => height.value, (v2, o2) => {
    cm.setSize(width.value, v2)
    cm.refresh()
})

</script>